//
//  AsyncDownload.m
//  first app
//
//  Created by 林 小明 on 14-7-10.
//
//

#import "AsyncDownload.h"
#import "FileCenter.h"

@implementation AsyncDownload

-(id)init
{
    if(self=[super init])
    {
        download_status = kDownloadStatusInit;
        total_size = 0;
        file_offset = 0;
        connection = nil;
        downloadInfo = [NSMutableDictionary dictionaryWithCapacity:10];
    }
    return self;
}

- (id)initWithDownloadFile:(NSString *)filename Path:(NSString *)dirpath Url:(NSString *)url
{
    if (self=[super init])
    {
        download_status = kDownloadStatusInit;
        total_size = 0;
        file_offset = 0;
        connection = nil;
        dir_path = dirpath;
        file_name = filename;
        download_url = url;
        downloadInfo = [NSMutableDictionary dictionaryWithCapacity:10];
        [downloadInfo setValue:url forKey:@"downloadurl"];
    }
    return self;
}

- (void)setDownloadFile:(NSString *)filename Path:(NSString *)dirpath Url:(NSString *)url
{
    dir_path = dirpath;
    file_name = filename;
    download_url = url;
}

- (BOOL)beforeDidDownload
{
    if( [file_name isEqualToString:@""] )
    {
        NSLog( @"download file name empty" );
        return NO;
    }
    else
    {
        if( [FileCenter IsFileExistInDocuments:dir_path fileName:file_name] )
        {
            //exist finish
            download_status = kDownloadStatusFinish;
        }
        else
        {
            NSString* file_downloadinfo_name = [NSString stringWithFormat:@"%@.dli", file_name];
            NSString* file_downloadtmp_name = [NSString stringWithFormat:@"%@.tmp", file_name];
            if( [FileCenter IsFileExistInDocuments:dir_path fileName:file_downloadinfo_name] &&
               [FileCenter IsFileExistInDocuments:dir_path fileName:file_downloadtmp_name] )
            {
                //continue
                NSLog( @"exist tmp file" );
                [self getDownloadInfo];
            }
            else
            {
                //first download
            }
        }
    }
    return YES;
}

- (void)getDownloadInfo
{
    NSString* file_downloadinfo_name = [NSString stringWithFormat:@"%@.dli", file_name];
    if([FileCenter IsFileExistInDocuments:dir_path fileName:file_downloadinfo_name])
    {
        NSString* content = [FileCenter ReadStringFile:dir_path fileName:file_downloadinfo_name];
        if( content!=nil )
        {
            NSArray *array = [content componentsSeparatedByString:@";"];
            if( [array count] >= 2 )
            {
                total_size = [(NSString*)[array objectAtIndex:0] longLongValue];
                file_offset = [(NSString*)[array objectAtIndex:1] longLongValue];
                
                NSLog( @"getDownloadInfo total_size:%lld, file_offset:%lld", total_size, file_offset );
            }
        }
    }
}

- (BOOL)downloadBegin
{
    NSMutableURLRequest *URLRequest = [
        [NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:download_url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10 ];
    
    [URLRequest setHTTPMethod:@"GET"];
    // 设置请求头文件
    NSString *rangeValue = [NSString stringWithFormat:@"bytes=%llu-", file_offset];
    [URLRequest addValue:rangeValue forHTTPHeaderField:@"Range"];
    
    //NSString *str = @"type=focus-c";//设置参数
    //NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    //[URLRequest setHTTPBody:data];
    //第三步，连接服务器
    
    download_status = kDownloadStatusStart;
    
    if ( connection == nil ) {
        connection = [[NSURLConnection alloc]initWithRequest:URLRequest delegate:self];
    }
    
    if (connection != nil) {
        //NSLog(@"connection ok");
    }else{
        NSLog(@"connection fail");
        return NO;
    }
    
    return YES;
}

- (BOOL)writeDownloadInfo:(NSData *)data
{
    [FileCenter CreateDocumentsDirectory:dir_path];
    long long offset = [FileCenter SaveToFile:dir_path fileName:[NSString stringWithFormat:@"%@.tmp",file_name] fileData:(NSData *)data fileOffset:file_offset];
    
    if( offset < 0 )
    {
        NSLog( @"save file error" );
        return NO;
    }
    
    file_offset = offset;
    
    NSString* content = [NSString stringWithFormat:@"%llu;%llu", total_size, file_offset];
    [FileCenter SaveToStringFile:dir_path fileName:[NSString stringWithFormat:@"%@.dli",file_name] fileData:content];
    
    return YES;
}

- (BOOL)copyDownloadDataToFile
{
    if( [FileCenter IsFileExistInDocuments:dir_path fileName:[NSString stringWithFormat:@"%@.tmp",file_name]] )
    {
        if ( [FileCenter CopyFile:dir_path srcFileName:[NSString stringWithFormat:@"%@.tmp",file_name] destDirName:dir_path destFileName:file_name] )
        {
            return YES;
        }
    }
    
    return NO;
}

- (void)startDownload
{
    if( [self beforeDidDownload] )
    {
        if ( download_status == kDownloadStatusFinish )
        {
            //file already exist
            return;
        }
        
        if (![self downloadBegin] )
        {
            return;
        }
    }
    else
    {
        //sth error
        return;
    }
}

- (void)stopDownload
{
    download_status = kDownloadStatusPause;
    [connection cancel];
    connection = nil;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    //NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
    //NSLog(@"%@",[res allHeaderFields]);
    
    unsigned long long contentLength = [response expectedContentLength];
    //NSString* fileName = [response suggestedFilename];
    
    if( total_size == 0 )
    {
        total_size = contentLength;
    }
    NSLog(@"receive response total_size:%lli file_offset:%lli", total_size, file_offset);
    
    [downloadInfo setValue:[NSNumber numberWithInt:download_status]
        forKey:@"downloadstatus"];
    [downloadInfo setValue:[NSNumber numberWithUnsignedLongLong:total_size] forKey:@"totalsize"];
    [downloadInfo setValue:[NSNumber numberWithUnsignedLongLong:file_offset] forKey:@"fileoffset"];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_DownloadProgress" object:downloadInfo userInfo:nil];
}

//接收到服务器传输数据的时候调用，此方法根据数据大小执行若干次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if ( ![self writeDownloadInfo: data] )
    {
        [self->connection cancel];
        download_status = kDownloadStatusError;
    }
    else
    {
        download_status = kDownloadStatusProcess;
    }
    
    [downloadInfo setValue:[NSNumber numberWithInt:download_status]
        forKey:@"downloadstatus"];
    [downloadInfo setValue:[NSNumber numberWithUnsignedLongLong:total_size] forKey:@"totalsize"];
    [downloadInfo setValue:[NSNumber numberWithUnsignedLongLong:file_offset] forKey:@"fileoffset"];
    
    NSLog(@"receive data total_size:%lli file_offset:%lli", total_size, file_offset);
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_DownloadProgress" object:downloadInfo userInfo:nil];
}

//数据传完之后调用此方法
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if( [self copyDownloadDataToFile] )
    {
        [FileCenter DeleteFile:dir_path fileName:[NSString stringWithFormat:@"%@.tmp",file_name]];
        [FileCenter DeleteFile:dir_path fileName:[NSString stringWithFormat:@"%@.dli",file_name]];
    }
    
    download_status = kDownloadStatusFinish;
    
    [downloadInfo setValue:[NSNumber numberWithInt:download_status]
        forKey:@"downloadstatus"];
    [downloadInfo setValue:[NSNumber numberWithUnsignedLongLong:total_size] forKey:@"totalsize"];
    [downloadInfo setValue:[NSNumber numberWithUnsignedLongLong:file_offset] forKey:@"fileoffset"];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_DownloadProgress" object:downloadInfo userInfo:nil];
}

//网络请求过程中，出现任何错误（断网，连接超时等）会进入此方法
-(void)connection:(NSURLConnection *)connection
 didFailWithError:(NSError *)error
{
    NSLog(@"%@",[error localizedDescription]);
}

@end
